package com.sl.proxy.server.controller;

import com.sl.proxy.server.base.page.PageInfo;
import com.sl.proxy.server.base.page.PageQuery;
import com.sl.proxy.server.constant.ExceptionConstant;
import com.sl.proxy.server.constant.NetworkProtocolEnum;
import com.sl.proxy.server.controller.req.proxy.*;
import com.sl.proxy.server.controller.res.proxy.PortMappingCreateRes;
import com.sl.proxy.server.controller.res.proxy.PortMappingDetailRes;
import com.sl.proxy.server.controller.res.proxy.PortMappingListRes;
import com.sl.proxy.server.controller.res.proxy.PortMappingUpdateEnableStatusRes;
import com.sl.proxy.server.service.PortMappingService;
import com.sl.proxy.server.util.ParamCheckUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/**
 * 端口映射
 *
 * @author: aoshiguchen
 * @date: 2022/8/8
 */
@RequestMapping("/port-mapping")
@RestController
@RequiredArgsConstructor
public class PortMappingController {
    private final PortMappingService portMappingService;

    @GetMapping("/page")
    public PageInfo<PortMappingListRes> page(PageQuery pageQuery, PortMappingListReq req) {
        ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");

        return portMappingService.page(pageQuery, req);
    }

    @PostMapping("/create")
    public PortMappingCreateRes create(@RequestBody PortMappingCreateReq req) {
        ParamCheckUtil.checkNotNull(req, "req");
        ParamCheckUtil.checkNotNull(req.getLicenseId(), "licenseId");
        ParamCheckUtil.checkNotNull(req.getServerPort(), "serverPort");
        ParamCheckUtil.checkNotNull(req.getClientPort(), "clientPort");
        ParamCheckUtil.checkNotEmpty(req.getProtocal(), "protocal");
        ParamCheckUtil.checkMaxLength(req.getDescription(), 50, "描述", "50");
        ParamCheckUtil.checkBytesDesc(req.getUpLimitRate(), "upLimitRate");
        ParamCheckUtil.checkBytesDesc(req.getDownLimitRate(), "downLimitRate");
        if (StringUtils.isBlank(req.getClientIp())) {
            // 没传客户端ip，默认为127.0.0.1
            req.setClientIp("127.0.0.1");
        }
        NetworkProtocolEnum networkProtocolEnum = NetworkProtocolEnum.of(req.getProtocal());
        ParamCheckUtil.checkNotNull(networkProtocolEnum, ExceptionConstant.AN_UNSUPPORTED_PROTOCOL, req.getProtocal());
        if (networkProtocolEnum != NetworkProtocolEnum.HTTP) {
            // 目前仅HTTP支持绑定域名
            req.setSubdomain(null);
        }
        req.setProtocal(networkProtocolEnum.getDesc());
        if (null == req.getProxyResponses()) {
            req.setProxyResponses(0);
        }
        if (null == req.getProxyTimeoutMs()) {
            req.setProxyTimeoutMs(0L);
        }
        if (null == req.getSecurityGroupId()) {
            req.setSecurityGroupId("0");
        }

        return portMappingService.create(req);
    }

    @PostMapping("/update")
    public void update(@RequestBody PortMappingUpdateReq req) {
        ParamCheckUtil.checkNotNull(req, "req");
        ParamCheckUtil.checkNotNull(req.getLicenseId(), "licenseId");
        ParamCheckUtil.checkNotNull(req.getServerPort(), "serverPort");
        ParamCheckUtil.checkNotNull(req.getClientPort(), "clientPort");
        ParamCheckUtil.checkNotEmpty(req.getProtocal(), "protocal");
        ParamCheckUtil.checkMaxLength(req.getDescription(), 50, "描述", "50");
        ParamCheckUtil.checkBytesDesc(req.getUpLimitRate(), "upLimitRate");
        ParamCheckUtil.checkBytesDesc(req.getDownLimitRate(), "downLimitRate");
        if (StringUtils.isBlank(req.getClientIp())) {
            // 没传客户端ip，默认为127.0.0.1
            req.setClientIp("127.0.0.1");
        }
        NetworkProtocolEnum networkProtocolEnum = NetworkProtocolEnum.of(req.getProtocal());
        ParamCheckUtil.checkNotNull(networkProtocolEnum, ExceptionConstant.AN_UNSUPPORTED_PROTOCOL, req.getProtocal());
        if (networkProtocolEnum != NetworkProtocolEnum.HTTP) {
            // 目前仅HTTP支持绑定域名
            req.setSubdomain(null);
        }
        req.setProtocal(networkProtocolEnum.getDesc());
        if (null == req.getProxyResponses()) {
            req.setProxyResponses(0);
        }
        if (null == req.getProxyTimeoutMs()) {
            req.setProxyTimeoutMs(0L);
        }
        if (null == req.getSecurityGroupId()) {
            req.setSecurityGroupId("0");
        }

        portMappingService.update(req);
    }

    @GetMapping("/detail")
    public PortMappingDetailRes detail(PortMappingDetailReq req) {
        ParamCheckUtil.checkNotNull(req, "req");
        ParamCheckUtil.checkNotNull(req.getId(), "id");

        return portMappingService.detail(req.getId());
    }

    @PostMapping("/update/enable-status")
    public PortMappingUpdateEnableStatusRes updateEnableStatus(@RequestBody PortMappingUpdateEnableStatusReq req) {
        ParamCheckUtil.checkNotNull(req, "req");
        ParamCheckUtil.checkNotNull(req.getId(), "id");
        ParamCheckUtil.checkNotNull(req.getEnable(), "enable");

        return portMappingService.updateEnableStatus(req);
    }

    @PostMapping("/delete")
    public void delete(@RequestBody PortMappingDeleteReq req) {
        ParamCheckUtil.checkNotNull(req, "req");
        ParamCheckUtil.checkNotNull(req.getId(), "id");

        portMappingService.delete(req.getId());
    }

    /**
     * 绑定安全组
     *
     * @param req portMappingId和securityGroupId
     */
    @PostMapping("/bind/security-group")
    public void bindSecurityGroup(@RequestBody PortMappingBindSecurityGroupReq req) {
        portMappingService.portBindSecurityGroup(req.getId(), req.getSecurityGroupId());
    }

    /**
     * 安全组解绑
     *
     * @param req 端口映射Id
     */
    @PostMapping("/unbind/security-group")
    public void unbindSecurityGroup(@RequestBody PortMappingUnbindSecurityGroupReq req) {
        portMappingService.portUnbindSecurityGroup(req.getId());
    }


}
